Skip to content

refactor: move lead-scoring compute core under schemes/lead_scoring/ [LTV-Pf.1]#109

Merged
shaypal5 merged 4 commits into
mainfrom
refactor/move-lead-scoring-compute-core
Jun 10, 2026
Merged

refactor: move lead-scoring compute core under schemes/lead_scoring/ [LTV-Pf.1]#109
shaypal5 merged 4 commits into
mainfrom
refactor/move-lead-scoring-compute-core

Conversation

@shaypal5

Copy link
Copy Markdown
Contributor

Summary

First half of the physical reorg (LTV-Pf.1, milestone LTV-M2).
Relocates the lead-scoring hidden-world compute core
simulation/, mechanisms/, structure/ — as whole directories under
leadforge/schemes/lead_scoring/, so the scheme owns its internals.

Hard break, no shims (decision D12): old import paths are removed and every
in-repo caller updated. Public API (leadforge.api, CLI) is unchanged and
generated bundles are byte-identical — only direct imports of these internal
modules break.

Mechanics

  • git mv of the three directories — 21 file renames, history preserved.
  • Repo-wide rewrite of the three absolute import prefixes across package +
    tests + scripts; no residual bare references:
old new
leadforge.simulation.* leadforge.schemes.lead_scoring.simulation.*
leadforge.mechanisms.* leadforge.schemes.lead_scoring.mechanisms.*
leadforge.structure.* leadforge.schemes.lead_scoring.structure.*

Scope (and what's deferred)

  • Not in this PR: render/{snapshots,relational,tasks} (that's LTV-Pf.2,
    which also splits render/relational.py so the shared write_relational_tables
    stays in the envelope), and the lead-scoring schema specs (split lands with
    LTV-Pg). Splitting LTV-Pf keeps each PR reviewable and byte-identical.
  • Known, intentional: core.models / render.relational carry TYPE_CHECKING-only
    references to the moved structure/simulation paths (a core→scheme type-only
    reference); the layering cleanup is tracked for M6.

Downstream consumer

The leadforge-datasets-private build scripts import these internals and must
update to the new paths — a breakage issue is being filed there. The package
stays on the 1.x line with a CHANGELOG "Moved" note (the public contract is
unchanged).

Verification

✅ BYTE-IDENTICAL vs main (14 files)
  • Full suite 1508 passed / 51 skipped; ruff + mypy clean; compileall
    clean for scripts/ + leadforge/.
  • BUNDLE_SCHEMA_VERSION unchanged.

🤖 Generated with Claude Code

…[LTV-Pf.1]

First half of the physical reorg (LTV-Pf). Relocates the lead-scoring
hidden-world compute core — simulation/, mechanisms/, structure/ — as whole
directories under leadforge/schemes/lead_scoring/, so the scheme owns its
internals. Hard break, no shims (decision D12): old import paths are removed
and every in-repo caller updated.

- git mv of the three directories (21 file renames; history preserved).
- Repo-wide rewrite of the three absolute import prefixes
  (leadforge.{simulation,mechanisms,structure} →
  leadforge.schemes.lead_scoring.{...}) across package, tests, and scripts;
  no residual bare references remain.
- Public API (leadforge.api, CLI) unchanged; package stays 1.x.
- CHANGELOG "Moved" note with the old→new path table; CLAUDE.md Repository Map
  updated; docs/ltv/roadmap.md + .agent-plan.md updated (Pf split into Pf.1
  compute core / Pf.2 render).

Scope: render/{snapshots,relational,tasks} and the lead-scoring schema specs
are NOT moved here — render relocation (with the relational.py split) is Pf.2;
the schema split lands with LTV-Pg. core.models / render.relational TYPE_CHECKING
hints now reference the new structure/simulation paths (a known core→scheme
type-only reference; layering cleanup tracked for M6).

Verified byte-identical to main (14/14 files of a pinned-timestamp bundle);
full suite 1508 passed / 51 skipped; ruff + mypy clean; scripts compile.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 10, 2026 14:13
@shaypal5 shaypal5 added this to the dataset: leadforge-ltv-v1 milestone Jun 10, 2026
@shaypal5 shaypal5 added type: refactor Code change with no behavior difference layer: structure structure/ motifs, graph, rewiring layer: mechanisms mechanisms/ generators and transitions layer: simulation simulation/ discrete-time engine status: needs review Ready for review dataset: leadforge-ltv-v1 Issue/PR scoped to the b2b_saas_ltv_v1 LTV dataset workstream labels Jun 10, 2026
Link PR #109, advance status. Next: LTV-Pf.2 (render move).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the lead-scoring scheme by physically relocating its compute core (simulation/, mechanisms/, structure/) under leadforge/schemes/lead_scoring/ and rewriting all in-repo import paths accordingly, while keeping the public API unchanged.

Changes:

  • Moved lead-scoring internal modules to leadforge.schemes.lead_scoring.{simulation,mechanisms,structure} and updated call sites across package code, tests, and scripts.
  • Updated scheme and project documentation (roadmap, changelog, repo layout docs) to reflect the new module locations and the intentional hard-break.
  • Adjusted Sphinx references / TYPE_CHECKING imports to point at the new module paths.

Reviewed changes

Copilot reviewed 39 out of 46 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/test_difficulty_modulation.py Updates mechanism-policy import to new scheme-owned path.
tests/structure/test_sampler.py Updates structure imports + module-path docstring.
tests/structure/test_rewiring.py Updates structure imports, including local imports inside tests.
tests/structure/test_node_types.py Updates node_types import path + module-path docstring.
tests/structure/test_motifs.py Updates motifs/node_types/graph imports + module-path docstring.
tests/structure/test_graph.py Updates graph/node_types imports + module-path docstring.
tests/simulation/test_population.py Updates simulation/structure imports, including a private helper import.
tests/simulation/test_engine.py Updates simulation/structure imports (multi-line import formatting).
tests/render/test_snapshot_windowed.py Updates render test imports to new scheme-owned simulation/structure paths.
tests/render/test_render.py Updates render test imports to new scheme-owned simulation/structure paths.
tests/mechanisms/test_mechanisms.py Updates mechanism imports to scheme-owned mechanisms package.
scripts/spike_category_signal.py Updates script imports to new scheme-owned simulation/structure paths.
leadforge/schemes/lead_scoring/structure/sampler.py Updates structure sampler imports and Sphinx references to new paths.
leadforge/schemes/lead_scoring/structure/rewiring.py Updates rewiring imports and Sphinx references to new paths.
leadforge/schemes/lead_scoring/structure/node_types.py Introduces scheme-owned NodeType definitions (StrEnum) and related sets.
leadforge/schemes/lead_scoring/structure/motifs.py Updates motifs’ imports and Sphinx references to new structure package.
leadforge/schemes/lead_scoring/structure/graph.py Updates node_types import to new scheme-owned location.
leadforge/schemes/lead_scoring/structure/init.py Package marker for relocated structure modules.
leadforge/schemes/lead_scoring/simulation/state.py Updates docstring Sphinx reference to new engine path.
leadforge/schemes/lead_scoring/simulation/population.py Updates TYPE_CHECKING WorldGraph import to new structure path.
leadforge/schemes/lead_scoring/simulation/engine.py Updates mechanisms/simulation/structure imports and doc references to new paths.
leadforge/schemes/lead_scoring/simulation/init.py Package marker for relocated simulation modules.
leadforge/schemes/lead_scoring/mechanisms/transitions.py Updates mechanisms imports and Sphinx references to new paths.
leadforge/schemes/lead_scoring/mechanisms/static.py Updates base mechanism imports to new paths.
leadforge/schemes/lead_scoring/mechanisms/scores.py Updates base mechanism imports and Sphinx references to new paths.
leadforge/schemes/lead_scoring/mechanisms/policies.py Updates mechanisms imports and Sphinx references to new paths.
leadforge/schemes/lead_scoring/mechanisms/measurement.py Updates base mechanism imports to new paths.
leadforge/schemes/lead_scoring/mechanisms/influence.py Updates base mechanism imports to new paths.
leadforge/schemes/lead_scoring/mechanisms/hazards.py Updates mechanism imports and Sphinx references to new paths.
leadforge/schemes/lead_scoring/mechanisms/counts.py Updates base mechanism imports to new paths.
leadforge/schemes/lead_scoring/mechanisms/categorical.py Updates base mechanism imports to new paths.
leadforge/schemes/lead_scoring/mechanisms/base.py Updates Sphinx reference to policy entry point under new path.
leadforge/schemes/lead_scoring/mechanisms/init.py Package marker for relocated mechanisms modules.
leadforge/schemes/lead_scoring/init.py Updates scheme docstring + imports used by build_world to new internal locations.
leadforge/render/snapshots.py Updates imports/TYPE_CHECKING references to new scheme-owned simulation paths.
leadforge/render/relational.py Updates TYPE_CHECKING references to new scheme-owned simulation paths.
leadforge/render/manifests.py Updates TYPE_CHECKING WorldGraph reference to new structure path.
leadforge/exposure/metadata.py Updates internal assign_mechanisms import to new scheme-owned path.
leadforge/core/models.py Updates TYPE_CHECKING references to scheme-owned simulation/structure paths.
docs/ltv/roadmap.md Updates roadmap narrative/split for Pf.1/Pf.2 and hard-break decision.
CLAUDE.md Updates repo layout documentation to reflect the new schemes/lead_scoring internal structure.
CHANGELOG.md Documents the internal-path breaking move and provides old→new import path mapping.
.agent-plan.md Updates project tracker text to reflect Pf split and hard-break decision.
Comments suppressed due to low confidence (11)

leadforge/schemes/lead_scoring/mechanisms/policies.py:34

  • The if TYPE_CHECKING: block is currently interleaved within the runtime import section, with additional imports following it. This breaks the import-block pattern used elsewhere in the repo and is likely to trip Ruff's import-sorting (I*) rules; it also makes it less clear which imports are type-only vs required at runtime.
    leadforge/schemes/lead_scoring/structure/rewiring.py:7
  • This docstring line exceeds the repo's 100-character line limit (Ruff E501). The longer module path after the refactor pushes it over; wrapping keeps lint green.
    leadforge/schemes/lead_scoring/simulation/engine.py:7
  • Several docstring lines here exceed the configured 100-character limit (Ruff E501) after the longer module paths were introduced. Wrapping these references keeps linting green.
    leadforge/schemes/lead_scoring/structure/rewiring.py:4
  • This docstring line is now over the 100-character limit (Ruff E501) due to the longer fully-qualified path. Please wrap the Sphinx reference onto its own line.
    leadforge/schemes/lead_scoring/structure/motifs.py:6
  • The new longer module path makes these docstring lines exceed the 100-character limit (Ruff E501). Wrapping avoids lint failures without changing meaning.
    leadforge/schemes/lead_scoring/mechanisms/scores.py:6
  • These docstring lines exceed the 100-character limit (Ruff E501) with the longer fully-qualified mechanism paths. Splitting the Sphinx references across lines keeps formatting/lint consistent.
    leadforge/schemes/lead_scoring/mechanisms/hazards.py:27
  • This docstring argument line is now long enough to violate the 100-character limit (Ruff E501). Wrapping the Sphinx reference onto its own indented line keeps the docstring readable and lint-clean.
    leadforge/schemes/lead_scoring/mechanisms/transitions.py:99
  • This docstring line likely exceeds the configured 100-character limit (Ruff E501) after expanding the fully-qualified path. Wrapping the Sphinx reference avoids lint failures.
    leadforge/schemes/lead_scoring/mechanisms/policies.py:244
  • This docstring summary line exceeds the 100-character limit (Ruff E501) with the longer fully-qualified class path. Splitting the description across lines keeps linting green.
    leadforge/schemes/lead_scoring/mechanisms/policies.py:258
  • These docstring lines are now long enough to violate the 100-character limit (Ruff E501) due to the expanded module paths. Wrapping the class references onto separate lines will keep linting green.
    leadforge/schemes/lead_scoring/simulation/state.py:5
  • This docstring line exceeds the 100-character limit (Ruff E501) after expanding the fully-qualified simulate_world path. Wrapping keeps linting green.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/ltv/roadmap.md Outdated
Comment on lines +125 to +127
- [x] **`LTV-Pf.1`** — compute core: `simulation/` + `mechanisms/` +
`structure/` moved as whole directories (21 file renames, all callers
rewritten). Verified byte-identical; full suite green. (**PR #NNN**)
Comment thread .agent-plan.md
Comment on lines +44 to +47
and `LTV-Pe` (#108) merged (scheme protocol + render seam). `LTV-Pf` (physical
move, **hard break / no shims** per D12) split into Pf.1 (compute core —
simulation/mechanisms/structure moved) opened as **#NNN**, and Pf.2 (render
move, pending). Verified byte-identical. Sibling `leadforge-datasets-private`
Comment on lines 78 to +81
Args:
result: Output of :func:`~leadforge.simulation.engine.simulate_world`.
result: Output of :func:`~leadforge.schemes.lead_scoring.simulation.engine.simulate_world`.
population: Output of
:func:`~leadforge.simulation.population.build_population`.
:func:`~leadforge.schemes.lead_scoring.simulation.population.build_population`.
Comment on lines 65 to +68
Args:
result: Output of :func:`~leadforge.simulation.engine.simulate_world`.
result: Output of :func:`~leadforge.schemes.lead_scoring.simulation.engine.simulate_world`.
population: Output of
:func:`~leadforge.simulation.population.build_population`.
:func:`~leadforge.schemes.lead_scoring.simulation.population.build_population`.
…-Pf.1]

Capture the follow-ups deferred by the peer-schemes reorg so they aren't lost:
- shared render orchestration (deferred in LTV-Pe),
- generalising build_manifest/apply_exposure off lead-scoring,
- removing the core->scheme TYPE_CHECKING inversion introduced in LTV-Pf.1.

Added a "Known deferred cleanups" section and an explicit deliverable bullet on
LTV-Pn (M6), where the manifest/exposure generalization makes them clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

This comment has been minimized.

…elf-review) [LTV-Pf.1]

Self-review of the move PR caught two gaps:
- CLAUDE.md "Package Layout (canonical)" still listed simulation/mechanisms/
  structure at top level while the "Repository Map" already showed them under
  schemes/lead_scoring/ — the file contradicted itself. Updated the canonical
  section to match (schemes/ block; render/ flagged as pending LTV-Pf.2).
- The hard-break decision (D12) was only asserted in prose. Added
  tests/schemes/test_module_layout.py: new scheme-owned paths import, old flat
  paths (incl. top-level packages) raise ModuleNotFoundError, and the public
  API (leadforge.api) still imports. Locks "no shims" in code so a future shim
  or an incomplete move fails CI.

Full suite 1524 passed / 51 skipped (+16); ruff + mypy clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

pr-agent-context report:

This run includes unresolved review comments on PR #109 in repository https://github.com/leadforge-dev/leadforge

For each unresolved review comment, recommend one of: resolve as irrelevant, accept and implement
the recommended solution, open a separate issue and resolve as out-of-scope for this PR, accept and
implement a different solution, or resolve as already treated by the code.

After I reply with my decision per item, implement the accepted actions, resolve the corresponding
PR comments, and push all of these changes in a single commit.

# Copilot Comments

## COPILOT-1
Location: docs/ltv/roadmap.md
URL: https://github.com/leadforge-dev/leadforge/pull/109#discussion_r3389075495
Status: outdated
Root author: copilot-pull-request-reviewer

Comment:
    This roadmap entry still contains the placeholder PR number `#NNN`. Before merging, this should be replaced with the real PR number or removed to avoid publishing stale placeholders in project docs.

## COPILOT-2
Location: .agent-plan.md:47
URL: https://github.com/leadforge-dev/leadforge/pull/109#discussion_r3389075569
Root author: copilot-pull-request-reviewer

Comment:
    This status update still contains the placeholder PR number `#NNN`. Before merging, replace it with the real PR number or remove it to avoid leaving an unresolved placeholder in the project tracker.

## COPILOT-3
Location: leadforge/render/snapshots.py:81
URL: https://github.com/leadforge-dev/leadforge/pull/109#discussion_r3389075602
Root author: copilot-pull-request-reviewer

Comment:
    This docstring line exceeds the configured 100-character limit (Ruff E501) after the import-path refactor. Splitting the `simulate_world` reference onto its own indented line keeps the docstring readable and lint-clean.

## COPILOT-4
Location: leadforge/render/relational.py:68
URL: https://github.com/leadforge-dev/leadforge/pull/109#discussion_r3389075642
Root author: copilot-pull-request-reviewer

Comment:
    This docstring line exceeds the 100-character limit (Ruff E501) after expanding the fully-qualified path. Wrap the Sphinx reference onto a continuation line to keep linting green.

Run metadata:

Tool ref: v4
Tool version: 4.0.21
Trigger: commit pushed
Workflow run: 27301852954 attempt 1
Comment timestamp: 2026-06-10T19:47:54.641198+00:00
PR head commit: 4c9812988bb7c1e1f9baf911869af582bbb0df3b

@shaypal5 shaypal5 merged commit 60c5e44 into main Jun 10, 2026
9 of 10 checks passed
@shaypal5 shaypal5 deleted the refactor/move-lead-scoring-compute-core branch June 10, 2026 19:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dataset: leadforge-ltv-v1 Issue/PR scoped to the b2b_saas_ltv_v1 LTV dataset workstream layer: mechanisms mechanisms/ generators and transitions layer: simulation simulation/ discrete-time engine layer: structure structure/ motifs, graph, rewiring status: needs review Ready for review type: refactor Code change with no behavior difference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants